// callback: cmd_plot
/**
 using plot command
 
 create a plotter:
   plot create buffer.name name
 
 delete a plotter:
   plot delete name | plot delete all
 
 setting a plot intersection surface:
   plot slab normal
   slab is the position of slab in the cell matrix (column/row)
   normal is the normal direction (x/y/z)
   
 plotter mode

 slab: contour plot of a slab
 lateral: lateral average on specific axis
 trace: line trace on an axis
 
   default ploter mode is slab
 
*/

void cmd_plot(istringstream& ss) {
  
  string op;
  ss>>op;
  
  // FIXME! here error handling need improvement...
  
  if(op=="create") {
    string a, b;
    ss>>a>>b;
    if(search_plotter(b)>=0) throw "plotter name exist";
    Buffer A; get_buffer(A,a);
    if(A.empty) throw "argument: buffer|domain:buffer name";
    if(b=="") {
      b="plotter-";
      b.append(as_string((int)plotter.size()));
    }
    plotter.push_back(new DriftPlotter(b,A));
    currentplot=plotter.size()-1;
  }
  
  else if(op=="delete") {
    string name;
    if(ss>>name) {
      int pid=search_plotter(name);
      if(pid<0) {
        if(name=="all") {
          for(int i=0;i<(int)plotter.size();i++) {
            delete plotter[i];
          }
          plotter.clear();
        } else throw "plotter name not found"; 
      } else {
        delete plotter[pid];
        plotter.erase(plotter.begin()+pid);
      }
    } else throw "required: name of plotter";
  }
  
  // slab plotter slab normal
  else if(op=="slab") {
    string name; int slab;
    char norm;
    if(ss>>name>>slab) {
      int pid=search_plotter(name);
      if(pid<0) throw "plotter not found";
      if(!(ss>>norm)) norm='z';
      plotter[pid]->init_slab(slab,norm);
    } else throw "syntax: slab plotter slab_number [normal]";
  }
  
  // lateral average of an axis
  else if(op=="lateral") {
    string name;
    char axis;
    if(ss>>name>>axis) {
      int pid=search_plotter(name);
      if(pid<0) throw "plotter not found";
      if(axis=='x'||axis=='y'||axis=='z') plotter[pid]->init_prof(axis);
      else throw "plot lateral: invalid axis";
    } else throw "syntax: lateral plotter axis";
  }

  // line tracing in an axis
  else if(op=="trace") {
      string name;
      char axis;
      int ta,tb;
      if(ss>>name>>axis>>ta>>tb) {
          throw "to be implemented...";
      } else throw "syntax: trace x|y|z cellx celly";
  }

  // sends a command to plotter
  else if(op=="send") {
    string name;
    string cmd;
    if(ss>>name) {
      int pid=search_plotter(name);
      if(pid<0){
        pid=currentplot;
        cmd.assign(name+" ");
      }
      cmd.append(getall(ss));
      plotter[pid]->send(cmd);
    }
  }
  
  // save plot to file (gnuplot script)
  else if(op=="save") {
    if(plotter.empty()) throw "plotter empty";
    string a,fname;
    if(!(ss>>a)) throw "file name required";
    int pid=search_plotter(a);
    if(pid<0) {
      pid=currentplot;
    } else {
      if(!(ss>>a)) throw "file name required";
    }

    plotter[pid]->save(get_filename(a));
  }

  // snap the plot screen
  else if(op=="snap") {
    if(plotter.empty()) throw "plotter empty";
    string a;
    if(!(ss>>a)) throw "file name required";
    int pid=search_plotter(a);
    if(pid<0) {
      pid=currentplot;
    } else {
      if(!(ss>>a)) throw "file name required";
    }
    a=get_filename(a);    
    plotter[pid]->snap(a);
  }
    
  else { // execute
    if(op.empty()) {
      if(plotter.empty()) throw "options: name,create,delete,slab,lateral,trace,send,save,snap";
      plotter[currentplot]->plot();
    } else {
      int pid=search_plotter(op);
      if(pid<0) throw "plotter not found";
      currentplot=pid;
      plotter[pid]->plot();
    }
  }
  
}
